package com.lxq.particledemo02;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

@SuppressLint("NewApi")
public class MyRenderer implements GLSurfaceView.Renderer {

    GLSurfaceView glView;
    private int textureId;

    private Context context;
    private final float[] projectionMatrix = new float[16];
    private final float[] viewMatrix = new float[16];
    private final float[] viewProjectionMatrix = new float[16];
    private ParticleShaderProgram particleProgram;
    private ParticleSystem particleSystem;
    private ParticleShooter redParticleShooter;
    private ParticleShooter greenParticleShooter;
    private ParticleShooter blueParticleShooter;
    private long globalStartTime;
    //private float globalStartTime;

    private final float angle = 5f;
    private final float speed = 1f;

    public MyRenderer(Context context, GLSurfaceView view) {
        this.context = context;
        this.glView = view;
    }


    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GLES20.glEnable(GLES20.GL_BLEND);
        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE);
        particleProgram = new ParticleShaderProgram(context, glView);
        particleSystem = new ParticleSystem(10000);
        globalStartTime = System.nanoTime();
        final Vector3 particleDirection = new Vector3(0f, 0.5f, 0f);
        redParticleShooter = new ParticleShooter(new Point3(-1f, 0f, 0f), particleDirection, Color.rgb(255, 50, 5), angle, speed);
        greenParticleShooter = new ParticleShooter(new Point3(0f, 0f, 0f), particleDirection, Color.rgb(25, 255, 25), angle, speed);
        blueParticleShooter = new ParticleShooter(new Point3(1f, 0f, 0f), particleDirection, Color.rgb(5, 50, 255), angle, speed);

        textureId = TextureUtil.loadTexture(context, R.mipmap.img_test);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
        Matrix.perspectiveM(projectionMatrix, 0, 45, (float) width / (float) height, 1f, 10f);
        Matrix.setIdentityM(viewMatrix, 0);
        Matrix.translateM(viewMatrix, 0, 0f, -1.5f, -5f);
        Matrix.multiplyMM(viewProjectionMatrix, 0, projectionMatrix, 0, viewMatrix, 0);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        float currentTime = (System.nanoTime() - globalStartTime) / 1000000000f;

        redParticleShooter.addParticles(particleSystem, currentTime, 5);
        greenParticleShooter.addParticles(particleSystem, currentTime, 5);
        blueParticleShooter.addParticles(particleSystem, currentTime, 5);


        particleProgram.useProgram();
        particleProgram.setUniforms(viewProjectionMatrix, currentTime, textureId);

        particleSystem.bindData(particleProgram);
        particleSystem.draw(particleProgram);
    }


    public FloatBuffer floatBufferUtil(float[] arr) {
        FloatBuffer mbuffer;
        ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
        qbb.order(ByteOrder.nativeOrder());

        mbuffer = qbb.asFloatBuffer();
        mbuffer.put(arr);
        mbuffer.position(0);

        return mbuffer;
    }

    public IntBuffer intBufferUtil(int[] arr) {
        IntBuffer mbuffer;
        ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
        qbb.order(ByteOrder.nativeOrder());

        mbuffer = qbb.asIntBuffer();
        mbuffer.put(arr);
        mbuffer.position(0);
        return mbuffer;
    }

}
